package com.example.controller.user;

import com.example.dto.request.user.UserSettingsRequestDTO;
import com.example.dto.request.user.UserSettingsRequestDTO.*;
import com.example.exception.user.InvalidPasswordException;
import com.example.exception.user.UnavailableUsernameException;
import com.example.pojo.User;
import com.example.response.ErrorStatus;
import com.example.response.ApiResult;
import com.example.dto.business.UserBusinessDTO;
import com.example.service.user.UserAuthenticationService;
import com.example.vo.user.UserSettingsRequestVO;
import com.example.service.user.UserSettingsService;
import com.example.service.user.impl.UserAuthorizationServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author Lexin Huang
 */
@Api(tags = "用户个人信息设置模块")
@Slf4j
@RestController
public class UserSettingsController {

    private final
    UserSettingsService userSettingsService;

    private final UserAuthorizationServiceImpl userAuthorizationService;

    private final UserAuthenticationService userAuthenticationService;

    public UserSettingsController(UserSettingsService userSettingsService,
                                  UserAuthorizationServiceImpl userAuthorizationService,
                                  UserAuthenticationService userAuthenticationService) {
        this.userSettingsService = userSettingsService;
        this.userAuthorizationService = userAuthorizationService;
        this.userAuthenticationService = userAuthenticationService;
    }

    @PatchMapping("/settings/security")
    @ApiOperation(value = "修改密码接口")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header")
    })
    public ApiResult<ApiResult.ApiData> changePassword(@RequestHeader(value = "token") String token,
                                                       @Validated(value = {ChangePasswordGroup.class})
                                                                    @RequestBody UserSettingsRequestDTO request) {
        User user = userAuthenticationService.login(token);
        try {
            if (!user.getPassword().equals(request.getOldPassword())) {
                throw new InvalidPasswordException("输入的密码与原密码不一致!");
            }
            user.setPassword(request.getNewPassword());
            userSettingsService.updatePassword(user);
            userAuthorizationService.refreshUserTokenCache(token, user);
            return ApiResult.buildNonDataSuccessResponse("修改成功!");
        } catch (InvalidPasswordException e) {
            log.info(e.getMessage());
            return ApiResult.buildErrorResponse(ErrorStatus.USER_PASSWORD_WRONG, e.getMessage());
        }
    }

    @PatchMapping("/settings/profile")
    @ApiOperation(value = "修改个人信息接口")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header"),
    })
    public ApiResult<UserSettingsRequestVO> modifyProfile(@RequestHeader("token") String token,
                                                          @Validated(value = {ModifyProfileGroup.class})
                                                                   @RequestBody UserSettingsRequestDTO requestDTO) throws Exception {
        User user = userAuthenticationService.login(token);
        ApiResult<UserSettingsRequestVO> response = new ApiResult<>();

        try {
            userSettingsService.modifyProfile(user, requestDTO);
            userAuthorizationService.refreshUserTokenCache(token, user);
            UserSettingsRequestVO data = new UserSettingsRequestVO(new UserBusinessDTO(user));
            response.setSuccess(data, "修改成功!");
        } catch (UnavailableUsernameException | DuplicateKeyException e) {
            response.setError(ErrorStatus.USERNAME_NOT_AVAILABLE);
        }
        return response;

    }

    @PatchMapping("/settings/avatar")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header"),
            @ApiImplicitParam(value = "图片文件", required = true,
                    dataTypeClass = MultipartFile.class, paramType = "form")
    })
    public ApiResult<UserSettingsRequestVO> uploadAvatar(@RequestHeader("token") String token,
                                                         @RequestParam("image") MultipartFile image) throws Exception {
        User user = userAuthenticationService.login(token);

        userSettingsService.replaceAvatar(user, image);
        UserBusinessDTO userInfo = new UserBusinessDTO();
        userInfo.setUserPortraitPath(user.getPortraitPath());
        UserSettingsRequestVO data = new UserSettingsRequestVO(userInfo);
        user.setPortraitPath(data.getUser().getUserPortraitPath());
        userAuthorizationService.refreshUserTokenCache(token, user);
        ApiResult<UserSettingsRequestVO> response = new ApiResult<>();
        response.setSuccess(data, "修改成功!");
        return response;
    }

    @GetMapping("/profile")
    @ApiOperation(value = "获取用户的个人信息")
    @ApiImplicitParam(value = "用户令牌", dataTypeClass = String.class, paramType = "header")
    public ApiResult<UserSettingsRequestVO> getUserProfile(@RequestHeader(value = "token") String token) {
        User user = userAuthenticationService.login(token);
        UserSettingsRequestVO data = new UserSettingsRequestVO(new UserBusinessDTO(user));
        ApiResult<UserSettingsRequestVO> response = new ApiResult<>();
        response.setSuccess(data);
        return response;

    }


}
